/*
 * string functions
 */
package helper

import (
	"errors"
	"fmt"
	"log"
	"math/rand"
	"regexp"
	"strconv"
	"strings"
	"time"
)

func ToString(v interface{}) string {
	var value string
	switch v.(type) {
	case string:
		value = v.(string)
	case int:
		value = strconv.Itoa(v.(int))
	case float64:
		value = strconv.FormatFloat(v.(float64), 'f', 2, 64)
	case float32:
		value = strconv.FormatFloat(float64(v.(float32)), 'f', 2, 64)
	case int64:
		value = strconv.FormatInt(v.(int64), 10)
	case []uint8:
		value = string(v.([]uint8))
		//	case []byte:
		//		value = string(v.([]byte))
	case interface{}:
		value = v.(string)
	case nil:
		value = ""
	default:
		log.Println("参数值类型错误", v, "not in string|int|float64|interface|int64")
	}
	return strings.Trim(value, " ")
}

func ToStr(v interface{}) string {
	var value string
	switch v.(type) {
	case string:
		value = v.(string)
	case int:
		value = strconv.Itoa(v.(int))
	case float64:
		value = strconv.FormatFloat(v.(float64), 'f', 0, 64)
	case float32:
		value = strconv.FormatFloat(float64(v.(float32)), 'f', 0, 64)
	case int64:
		value = strconv.FormatInt(v.(int64), 10)
	case []uint8:
		value = string(v.([]uint8))
		//	case []byte:
		//		value = string(v.([]byte))
	case interface{}:
		value = v.(string)
	case nil:
		value = ""
	default:
		log.Println("参数值类型错误", v, "not in string|int|float64|interface|int64")
	}
	return strings.Trim(value, " ")
}

func ToFloat64(v interface{}) (float64, error) {
	var value float64
	var err error = nil
	switch v.(type) {
	case string:
		v_tmp := v.(string)
		value, _ = strconv.ParseFloat(v_tmp, 64)
	case int:
		value = float64(v.(int))
	case int64:
		value = float64(v.(int64))
	case float64:
		value = v.(float64)
	case interface{}:
		value = v.(float64)
	case nil:
		value = 0
	default:
		err = errors.New("参数值类型错误")
		log.Println("参数值类型错误", v, "not in string|int|float64|interface|int64")
	}
	return value, err
}

func ToInt(inter interface{}) int {
	var value int

	switch inter.(type) {

	case string:
		value, _ = strconv.Atoi(inter.(string))
	case int:
		value = inter.(int)
	case int64:
		value = int(inter.(int64))
	case float64:
		value, _ = strconv.Atoi(fmt.Sprintf("%1.0f", inter))
	case nil:
		value = 0
	case interface{}:
		value = inter.(int)
	default:
		log.Println("参数值类型错误", inter, "not in string|int|float64|interface|int64")
	}
	return value
}

func ToInt64(inter interface{}) int64 {
	var value int64

	switch inter.(type) {

	case string:
		value, _ = strconv.ParseInt(inter.(string), 10, 64)
	case int:
		value = int64(inter.(int))
	case int64:
		value = inter.(int64)
	case float64:
		value_int, _ := strconv.Atoi(fmt.Sprintf("%1.0f", inter))
		value = int64(value_int)
	case nil:
		value = 0
	case interface{}:
		if _, ok := inter.(int64); !ok {
			value = inter.(int64)
		}
	default:
		log.Println("参数值类型错误", inter, "not in string|int|float64|interface|int64")
	}
	return value
}

//生成随机字符串
func GetRandomString(length int) string {
	str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	bytes := []byte(str)
	result := []byte{}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < length; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return string(result)
}

//生成随机数字
func GetRandomNumber(length int) string {
	str := "0123456789"
	bytes := []byte(str)
	result := []byte{}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < length; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return string(result)
}

/**
 * 字符串转大驼峰 ios_bbbbbbbb -> IosBbbbbbbbb
 */
func StrFirstToUpper(str string) string {
	str = strings.ReplaceAll(str, "`", "")
	temp := strings.Split(str, "_")
	var upperStr string
	for y := 0; y < len(temp); y++ {
		vv := []rune(temp[y])
		for i := 0; i < len(vv); i++ {
			if i == 0 {
				vv[i] -= 32
				upperStr += string(vv[i])
			} else {
				upperStr += string(vv[i])
			}
		}
	}
	return upperStr
}

/**
 * 是否存在在字符切片中
 */
func IsInStringArray(arr []string, str string) bool {
	var isIn bool = false
	length := len(arr)
	if length < 1 {
		return false
	}
	for _, item := range arr {
		if item == str {
			isIn = true
			break
		}
	}
	return isIn
}

/**
 * 字符串在字符切片中对应索引
 */
func InStringArrayIndex(arr []string, str string) int {
	// var isIn bool = false
	length := len(arr)
	if length < 1 {
		return -1
	}
	var index int = -1
	for k, item := range arr {
		if item == str {
			// isIn = true
			index = k
			break
		}
	}
	return index
}

/*
 * 删除多余空格
 * 2019/05/05
 */
func DeleteExtraSpace(s string) string {
	s1 := strings.Replace(s, "	", " ", -1) //替换tab
	regstr := "\\s{2,}"                    //两个及两个以上空格的正则表达式
	reg, _ := regexp.Compile(regstr)       //编译正则表达式
	s2 := make([]byte, len(s1))
	copy(s2, s1)
	spc_index := reg.FindStringIndex(string(s2)) //在字符串中搜索
	for len(spc_index) > 0 {
		s2 = append(s2[:spc_index[0]+1], s2[spc_index[1]:]...) //删除多余空格
		spc_index = reg.FindStringIndex(string(s2))
	}
	return string(s2)
}

/*
 * 连接多个字符串
 * 2019/05/05
 */
func StringJoin(s ...string) string {
	var build strings.Builder
	if len(s) > 0 {
		for _, v := range s {
			build.WriteString(v)
		}
	}

	return build.String()
}

/*
 * 连接url
 * 2019/05/05
 */
func UrlJoin(host, url string) string {
	if strings.Contains(url, "http://") {
		return url
	}
	if strings.Contains(url, "https://") {
		return url
	}

	return StringJoin(host, url)
}


/**
 * 去除字符串的html标签
 * @2021/10/20
 */
func TrimHtml(src string) string {
	//将HTML标签全转换成小写
	re, _ := regexp.Compile("\\<[\\S\\s]+?\\>")
	src = re.ReplaceAllStringFunc(src, strings.ToLower)
	//去除STYLE
	re, _ = regexp.Compile("\\<style[\\S\\s]+?\\</style\\>")
	src = re.ReplaceAllString(src, "")
	//去除SCRIPT
	re, _ = regexp.Compile("\\<script[\\S\\s]+?\\</script\\>")
	src = re.ReplaceAllString(src, "")
	//去除所有尖括号内的HTML代码，并换成换行符
	re, _ = regexp.Compile("\\<[\\S\\s]+?\\>")
	src = re.ReplaceAllString(src, "\n")
	//去除连续的换行符
	re, _ = regexp.Compile("\\s{2,}")
	src = re.ReplaceAllString(src, "\n")
	return strings.TrimSpace(src)
}


/**
 * 腾讯云图片压缩
 * @2021/11/19
 * @linsen
 */
func TencentCloudImageCompress(imgUrl,ratio string)string{
	return imgUrl + "?imageMogr2/thumbnail/"+ ratio +"x/interlace/1"
}